#ifndef DATASTRUCTURES_H
#define DATASTRUCTURES_H

#include <opencv2/core/core.hpp>

#ifndef PI
#define PI 3.14159265
#endif

struct LineSegmentI
{
    int x0;
    int y0;
    int x1;
    int y1;

    LineSegmentI() {
        x0 = y0 = x1 = y1 = 0;
    }
};

struct LineSlopeF
{
    float x0;
    float y0;
    float slopeX;
    float slopeY;

    LineSlopeF() {
        x0 = y0 = slopeX = slopeY = 0;
    }
};

struct LineSegmentF
{
    float x0;
    float y0;
    float x1;
    float y1;

    LineSegmentF() {
        x0 = y0 = x1 = y1 = 0;
    }
};

struct LineSegRect
{
    LineSegmentF l;
    LineSegmentF r;
    LineSegmentF t;
    LineSegmentF b;
};

struct RectPt
{
    cv::Point2f tl;
    cv::Point2f tr;
    cv::Point2f bl;
    cv::Point2f br;
};

// location of the calibration target in the depth and rgb image
struct CalibrationLocation
{
    RectPt depth;
    RectPt rgb;
};

class StereoCalib
{
public:
    StereoCalib( int numCoef ) {
        firstCoef = cv::Mat::zeros(numCoef, 1, CV_64F);
        secondCoef = cv::Mat::zeros(numCoef, 1, CV_64F);
        firstK = cv::Mat::zeros(3, 3, CV_64F);
        secondCoef = cv::Mat::zeros(3, 3, CV_64F);

        R = cv::Mat::zeros(3, 3, CV_64F);
        T = cv::Mat::zeros(3, 1, CV_64F);

        E = cv::Mat::zeros(3, 3, CV_64F);
        F = cv::Mat::zeros(3, 3, CV_64F);
    }

    int numCoefs() {
        return firstK.rows;
    }

    cv::Mat firstK;
    cv::Mat firstCoef;
    cv::Mat secondK;
    cv::Mat secondCoef;
    // transform from first to second
    cv::Mat R;
    cv::Mat T;

    cv::Mat E;
    cv::Mat F;
};


class ContourCorner
{
public:
    // the index of the point in the contour
    int index;
    // pixel location of the contour
    int x;
    int y;
    // direction the corner is pointing in
    double direction;

    ContourCorner();
    ContourCorner( int index , int x , int y , double direction ) {
        this->index = index;
        this->x = x;
        this->y = y;
        this->direction = direction;
    }
};


#endif // DATASTRUCTURES_H
